#include "WindowSettings.hpp"

namespace sl
{
	WindowSettings::WindowSettings() : myMode(), myCaption(""), myStyle(0), mySettings()
	{}

	WindowSettings::WindowSettings(sf::VideoMode mode, const std::string& caption, char style, const sf::ContextSettings& settings) : myMode(mode), myCaption(caption), myStyle(style), mySettings(settings)
	{
		myFullscreen = static_cast<bool>(style >> 3);
	}

	WindowSettings* WindowSettings::Create(sf::VideoMode mode, const std::string& caption, char style, const sf::ContextSettings& settings)
	{
		myMode = mode;
		myCaption = caption;
		myStyle = style;
		myFullscreen = static_cast<bool>(style >> 3);
		mySettings = settings;
		return this;
	}

	sf::VideoMode WindowSettings::GetMode()
	{
		return myMode;
	}

	WindowSettings* WindowSettings::SetMode(const sf::VideoMode& videomode)
	{
		myMode = videomode;
		return this;
	}

	short WindowSettings::GetStyle()
	{
		return myStyle;
	}

	WindowSettings* WindowSettings::SetStyle(char style)
	{
		myStyle = style;
		return this;
	}

	sf::ContextSettings WindowSettings::GetSettings()
	{
		return mySettings;
	}

	WindowSettings* WindowSettings::SetSettings(const sf::ContextSettings& settings)
	{
		mySettings = settings;
		return this;
	}

	std::string WindowSettings::GetCaption()
	{
		return myCaption;
	}

	WindowSettings* WindowSettings::SetCaption(const std::string& caption)
	{
		myCaption = caption;
		return this;
	}

	bool WindowSettings::GetFullscreen()
	{
		return myFullscreen;
	}

	WindowSettings* WindowSettings::SetFullscreen(bool fullscreen)
	{
		myFullscreen = fullscreen;
		return this;
	}

	WindowSettings* WindowSettings::LoadFromFile(const pugi::xml_node* node)
	{
		if (node == NULL)
			return NULL;

		node = &node->child("window");

		unsigned int width, height, bpp;
		width = Default(node->attribute("width").as_uint(), 640);
		height = Default(node->attribute("height").as_uint(), 480);
		bpp = Default(node->attribute("bpp").as_uint(), 32);
		myMode = sf::VideoMode(width, height, bpp);

		myStyle = Default(node->attribute("style").as_uint(), sf::Style::Close);

		unsigned int depth, stencil, antialiasing, major, minor;
		depth = Default(node->attribute("depth").as_uint(), 24);
		stencil = Default(node->attribute("stencil").as_uint(), 8);
		antialiasing = Default(node->attribute("antialiasing").as_uint(), 0);
		major = Default(node->attribute("major").as_uint(), 2);
		minor = Default(node->attribute("minor").as_uint(), 0);
		mySettings = sf::ContextSettings(depth, stencil, antialiasing, major, minor);

		myCaption = Default(Convert(node->attribute("caption").value()), "Default");
		myFullscreen = Default(node->attribute("fullscreen").as_bool(), false);

		return this;
	}

	WindowSettings* WindowSettings::SaveToFile(const std::string& filename)
	{
		return SaveToFile(&pugi::xml_document(), filename);
	}

	WindowSettings* WindowSettings::SaveToFile(pugi::xml_node* node, const std::string& filename)
	{
		if (node == NULL)
			return this;

		node = &node->append_child("window");

		node->append_attribute("width").set_value(myMode.Width);
		node->append_attribute("height").set_value(myMode.Height);
		node->append_attribute("bpp").set_value(myMode.BitsPerPixel);

		node->append_attribute("style").set_value(myStyle);

		node->append_attribute("depth").set_value(mySettings.DepthBits);
		node->append_attribute("stencil").set_value(mySettings.StencilBits);
		node->append_attribute("antialiasing").set_value(mySettings.AntialiasingLevel);
		node->append_attribute("major").set_value(mySettings.MajorVersion);
		node->append_attribute("minor").set_value(mySettings.MinorVersion);

		node->append_attribute("caption").set_value(myCaption.c_str());
		node->append_attribute("fullscreen").set_value(myFullscreen);

		SaveToFile(node, filename);

		return this;
	}

	std::ostream& operator<<(std::ostream& os, const WindowSettings& settings)
	{
		os << settings.myMode.Width << settings.myMode.Height << settings.myMode.BitsPerPixel;
		os << settings.myStyle;
		os << settings.mySettings.DepthBits << settings.mySettings.StencilBits << settings.mySettings.AntialiasingLevel << settings.mySettings.MajorVersion << settings.mySettings.MinorVersion;
		os << settings.myCaption;
		os << settings.myFullscreen;
		return os;
	}

	std::istream& operator>>(std::istream& is, WindowSettings& settings)
	{
		unsigned int width, height, bpp;
		is >> width >> height >> bpp;
		settings.myMode = sf::VideoMode(width, height, bpp);

		is >> settings.myStyle;

		unsigned int depth, stencil, antialiasing, major, minor;
		is >> depth >> stencil >> antialiasing >> major >>  minor;
		sf::ContextSettings(depth, stencil, antialiasing, major, minor);

		is >> settings.myCaption;

		is >> settings.myFullscreen;

		return is;
	}
}